package com.videri.match.client;

import java.util.Arrays;
import java.util.Collections;

import com.allen_sauer.gwt.dragdrop.client.PickupDragController;
import com.allen_sauer.gwt.dragdrop.client.drop.DropController;
import com.allen_sauer.gwt.dragdrop.client.drop.NoOverlapDropController;
import com.allen_sauer.gwt.dragdrop.client.util.DOMUtil;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;

public class PlayGame extends MatchSink {

	private AbsolutePanel myAbsolutePanel = new AbsolutePanel();
	private ImageRegion[] myImageRegions;
	private StringBoxPair[] myStringBoxes;
	private static final String CSS_LABEL_STYLE = "match-string-style";

	public static MatchSinkInfo init(){
		return new MatchSinkInfo("Play Matching Game") {
			public MatchSink createInstance(){
				return new PlayGame(null);
			}

			public String getColor(){
				// You can change this to change the color of the tab for this option
				return "#56B526";
			}
		};
	}

	public PlayGame(Matching m)
	{
		initWidget(myAbsolutePanel);
		if(m == null)
			return;
		initialize(m);
	}	

	public void initialize(final Matching m){
		System.out.println("PlayGame is initializing");
		myAbsolutePanel.clear();
//		HorizontalSplitPanel hsp = new HorizontalSplitPanel();
		HorizontalPanel hp = new HorizontalPanel();
		final VerticalPanel vp = new VerticalPanel();
		vp.setWidth("20em");
		vp.add(new Button("Check Solution", new ClickListener() {
			public void onClick(Widget sender) {
				boolean winner = true;
				int i=0;
				Widget[] w;
				switch(m.my2Type) {
				case Matching.ImageRegion:
					while(winner && i<myImageRegions.length) {
						w = myImageRegions[i].getDropped();
						if (w.length > 0)
							winner = m.isMatch(((Label)(w[0])).getText(),myImageRegions[i].getRegion());
						else winner = false;
						i++;
					}
					break;
				case Matching.String:
					while(winner && i<m.myStrings2.length) {
						w = myStringBoxes[i].getDropped();
						if (w.length > 0)
							winner = m.isMatch(((Label)(w[0])).getText(),m.myStrings2[i]);
						else winner = false;
						i++;
					}
					break;
				case Matching.Image:
					while(winner && i<m.myImages2.length) {
						w = myStringBoxes[i].getDropped();
						if (w.length > 0)
							winner = m.isMatch(((Label)(w[0])).getText(),new Image(m.myImages2[i]));
						else winner = false;
						i++;
					}
					break;
				}
				if(winner) vp.add(new Label("WINNER!!!"));
				else vp.add(new Label("LOSER!!!"));
			}
		}));
		
		SourceListDropController sourceList = new SourceListDropController(vp);

		PickupDragController pdc = new PickupDragController(myAbsolutePanel, false);
		pdc.registerDropController(sourceList);

		System.out.println("Panel setup complete");

		//Set up left side
		switch(m.my1Type)
		{
		case Matching.String: //If we're matching Strings to X:
			for(int i = 0; i < m.myStrings1.length; i++)
			{
				Label l = new Label(m.myStrings1[i], false);
				l.addStyleName(CSS_LABEL_STYLE);
				l.setWidth(l.getText().length() + "em");
				l.setHorizontalAlignment(Label.ALIGN_CENTER);
				//vp.add(l);
				sourceList.addWidget(l);
				pdc.makeDraggable(l);
			}
			break;
		case Matching.Image:
			for(int i = 0; i < m.myImages1.length; i++)
			{
				Image ii = new Image(m.myImages1[i]);
				vp.add(ii);
				pdc.makeDraggable(ii);
			}
			break;
		default:
			System.err.println("PlayGame Error: m.my1Type is Invalid ("+m.my1Type+")");
		break;
		}
//		hsp.setLeftWidget(vp);
		hp.add(vp);
		System.out.println("Left Set Up");

		//Set Up Right Side
		AbsolutePanel ap2 = new AbsolutePanel();
		NoOverlapDropController nodc = new NoOverlapDropController(ap2);

		pdc.registerDropController(nodc);

		switch(m.my2Type)
		{
		case Matching.String:
			int[] s = shuffledList(m.myStrings2.length);
			myStringBoxes = new StringBoxPair[m.myStrings2.length];
			for(int i = 0; i < m.myStrings2.length; i++)
			{
				StringBoxPair sbp = new StringBoxPair(m.myStrings2[s[i]],Random.nextInt(255),Random.nextInt(255),Random.nextInt(255));
				ap2.add(sbp);
				pdc.registerDropController(sbp.getDropController());
				myStringBoxes[s[i]] = sbp;
			}
			break;
		case Matching.ImageRegion:
			ap2.add(m.getBackground(),-1,-1);
			myImageRegions = new ImageRegion[m.myImageRegions2.length];
			for(int i = 0; i < m.myImageRegions2.length; i++)
			{
				ImageRegion ir = new ImageRegion(m.myImageRegions2[i], Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
				pdc.registerDropController(ir.getDropController());
				addImageRegion(ap2, ir);
				myImageRegions[i] = ir;
			}
			break;
		case Matching.Image:
			int[] s2 = shuffledList(m.myImages2.length);
			myStringBoxes = new StringBoxPair[m.myImages2.length];
			for(int i = 0; i < m.myImages2.length; i++)
			{
				StringBoxPair sbp = new StringBoxPair(new Image(m.myImages2[s2[i]]),Random.nextInt(255),Random.nextInt(255),Random.nextInt(255));
				ap2.add(sbp);
				pdc.registerDropController(sbp.getDropController());
				myStringBoxes[s2[i]] = sbp;
			}
			break;
		}
//		hsp.setRightWidget(ap2);
		hp.add(ap2);
		myAbsolutePanel.add(hp,-1,-1);
		System.out.println("Right Set Up");
	}

	public static void addImageRegion(AbsolutePanel sp, ImageRegion ir)
	{
		sp.add(ir, ir.getX(), ir.getY());
	}
	
	/**
	 * creates a shuffled array of ints from 0 to
	 * length-1
	 * @param length
	 * @return
	 */
	public static int[] shuffledList(int length) {
		int[] list = new int[length];
		for(int i=0;i<length;i++) list[i] = i;
		for(int i=0;i<length;i++) swapRandom(list);
		return list;
	}
	
	/**
	 * swaps two random elements of list
	 * @param list
	 */
	public static void swapRandom(int[] list) {
		int i1 = Random.nextInt(list.length);
		int i2 = Random.nextInt(list.length);
		int temp = list[i1];
		list[i1] = list[i2];
		list[i2] = temp;
	}
}
